﻿using System;
using System.Collections.Generic;
using System.Web;
using System.Web.Mvc;
using Framework.Poco;
using System.IO;
using Framework.Mvc.ViewModels;
using Shell.DomainDot;
using Framework.Domain;
using System.Linq;
using System.Text.RegularExpressions;

namespace Framework.Mvc.Controllers
{
    /// <summary>
    /// 文件控制器
    /// </summary>
    public class FileController : Controller
    {
        private const string uploadFormName = "filedata";//表单文件域name
        private const string dispositonName = "HTTP_CONTENT_DISPOSITION";
        private const string dispositonFilenameRegex = "filename=\"(.+?)\"";
        private const string jsonContentType = "text/x-json";
        private static int maxAllowedUploadLength = 2097152;
        private IDomainDotFactory factory;

        /// <summary>
        /// 文件构造器
        /// </summary>
        public FileController()
        {
            factory = DomainDotFactory.Factory;
        }

        /// <summary>
        /// 上传
        /// </summary>
        [HttpGet]
        public ActionResult Upload()
        {
            return View();
        }

        /// <summary>
        /// 提交图片
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        [ActionName("Upload")]
        public JsonResult PostUpload()
        {
            var list = new List<FileUploaded>();
            bool isSuccessed = false;
            foreach (string file in Request.Files)
            {
                HttpPostedFileBase postFile = Request.Files[file];
                if (postFile.ContentLength > 0 && postFile.ContentLength < maxAllowedUploadLength)
                {
                    var buffer = ToBytes(postFile.InputStream);
                    var f = new BinaryFile
                    {
                        Id = Guid.NewGuid(),
                        Mime = postFile.ContentType,
                        Name = postFile.FileName,
                        Data = buffer,
                        Length = buffer.LongLength,
                        Created = DateTime.Now
                    };
                    var context = factory.Create<BinaryFileContext>();
                    var newfile = context.CreateBinaryFile(f);
                    list.Add(new FileUploaded(newfile.Id, newfile.Name));
                    isSuccessed = true;
                }
            }
            var model = new FileUploadViewModel
            {
                IsSuccessed = isSuccessed,
                List = list
            };
            return Json(model, jsonContentType);
        }

        public ActionResult Details(Guid identity)
        {
            var context = factory.Create<BinaryFileContext>();
            var file = context.GetBinaryFile(identity);
            if (file != null)
            {
                return new FileContentResult(file.Data.ToArray(), file.Mime)
                {
                    FileDownloadName = file.Name
                };
            }
            else
            {
                return this.View(); //TODO 这里以后可以直接返回一张告知文件不存在的图片
            }
        }

        public ActionResult XheEditorUpload()
        {
            var result = new XhEditorUploadResult();
            byte[] fileBuffer = null;
            string filename = String.Empty;
            string contentType = String.Empty;

            string disposition = this.Request.ServerVariables[dispositonName];
            if (disposition != null)
            {
                // HTML5上传
                fileBuffer = this.Request.BinaryRead(Request.TotalBytes);
                filename = Regex.Match(disposition, dispositonFilenameRegex).Groups[1].Value;// 读取原始文件名
                //contentType = ""; //TODO
            }
            else
            {
                var postedfile = this.Request.Files.Get(uploadFormName);
                if (postedfile != null)
                {
                    filename = postedfile.FileName;
                    fileBuffer = ToBytes(postedfile.InputStream);
                    contentType = postedfile.ContentType;
                }
            }

            if (fileBuffer != null && fileBuffer.Length > 0 && !String.IsNullOrEmpty(filename))
            {
                if (fileBuffer.Length <= maxAllowedUploadLength)
                {
                    var f = new BinaryFile
                    {
                        Mime = contentType,
                        Name = filename,
                        Data = fileBuffer,
                        Length = fileBuffer.LongLength,
                        Created = DateTime.Now
                    };
                    var context = factory.Create<BinaryFileContext>();
                    var picture = context.CreateBinaryFile(f);

                    result.msg.url = new Uri("/File/Details/" + picture.Id.ToString(), UriKind.Relative).ToString();
                    result.msg.localname = filename;
                    result.msg.id = f.Id.ToString();
                }
                else
                {
                    result.err = String.Format("文件大小超过{0}字节", maxAllowedUploadLength);
                }
            }
            else
            {
                result.err = "无数据提交";
            }

            fileBuffer = null;
            return Json(result, jsonContentType);
        }

        [NonAction]
        private byte[] ToBytes(Stream inputStream)
        {
            int b1;
            var tempStream = new MemoryStream();
            while ((b1 = inputStream.ReadByte()) != -1)
            {
                tempStream.WriteByte(((byte)b1));
            }
            return tempStream.ToArray();
        }

        class XhEditorUploadResult
        {
            public XhEditorUploadResult()
            {
                this.err = String.Empty;
                this.msg = new XhEditorUploadResultMessage();
            }

            public string err { get; set; }
            public XhEditorUploadResultMessage msg { get; set; }
        }

        class XhEditorUploadResultMessage
        {
            public XhEditorUploadResultMessage()
            {
                this.url = this.localname = this.id = String.Empty;
            }

            public string url { get; set; }
            public string localname { get; set; }
            public string id { get; set; }
        }
    }
}